using System.Collections.Generic;
using System.Diagnostics;

////////////////////////////////////////////////////////////////////////////////
///
/// A buffer class for temporarily storaging sound samples, operates as a
/// first-in-first-out pipe.
///
/// Samples are added to the end of the sample buffer with the 'putSamples'
/// function, and are received from the beginning of the buffer by calling
/// the 'receiveSamples' function. The class automatically removes the
/// outputted samples from the buffer, as well as grows the buffer size
/// whenever necessary.
///
/// Author        : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed  : $Date: 2009-02-27 19:24:42 +0200 (Fri, 27 Feb 2009) $
// File revision : $Revision: 4 $
//
// $Id: FIFOSampleBuffer.cpp 68 2009-02-27 17:24:42Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
//  SoundTouch audio processing library
//  Copyright (c) Olli Parviainen
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
////////////////////////////////////////////////////////////////////////////////

namespace soundtouch
{
	public class FIFOSampleBuffer
	{
		/// Sample buffer.
		public List<float> buffer;

		/// Channels, 1=mono, 2=stereo.
		uint channels;

		// Constructor
		public FIFOSampleBuffer()
		{;
			buffer = new List<float>();
		}

		// Sets number of channels, 1 = mono, 2 = stereo
		public void setChannels(int numChannels)
		{
			Debug.Assert(numChannels > 0);			
			channels = (uint)numChannels;
		}

		// Adds 'numSamples' pcs of samples from the 'samples' memory position to
		// the sample buffer.
		public void putSamples(float[] samples, uint decSamples)
		{
			List<float> temp = new List<float>(samples);
			
			this.buffer.AddRange(temp.GetRange(0, (int)decSamples));
		}

		// Returns the current buffer capacity in terms of samples
		public int getCapacity()
		{
			return this.buffer.Count;
		}


		// Returns the number of samples currently in the buffer
		public int numSamples()
		{
			return (int)(this.buffer.Count / this.channels);
		}


		// Output samples from beginning of the sample buffer. Copies demanded number
		// of samples to output and removes them from the sample buffer. If there
		// are less than 'numsample' samples in the buffer, returns all available.
		//
		// Returns number of samples copied.
		public void receiveSamples(float[] samples, uint maxSamples)
		{
			List<float> samplesTemp = new List<float>();
			
			int num = (int)maxSamples < this.buffer.Count ? (int)maxSamples : this.buffer.Count;
			
			samples = this.buffer.GetRange(0, num - 1).ToArray();
			
			samples = samplesTemp.ToArray();
			
			this.receiveSamples((uint)num);
		}
		
		public void receiveSamples(uint maxSamples)
		{
			int num = (int)maxSamples < this.buffer.Count ? (int)maxSamples : this.buffer.Count;
			
			this.buffer.RemoveRange(0, num - 1);
		}

		// Returns nonzero if the sample buffer is empty
		public bool isEmpty()
		{
			return this.buffer.Count == 0;
		}


		// Clears the sample buffer
		public void clear()
		{
			this.buffer.Clear();
		}
		
	}
}
